package com.shootforthestars.objects;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;

import com.shootforthestars.components.CollisionComponent;
import com.shootforthestars.components.LifeComponent;
import com.shootforthestars.components.MotionComponent;
import com.shootforthestars.core.Actor;
import com.shootforthestars.core.Collidable;
import com.shootforthestars.util.ImageManager;

/**
 * @author jmcomets
 */
public class Rocket implements Actor, Collidable {
	private static final int MAX_LIFE = 100;
	private static final Vector2f GRAVITY = new Vector2f(0, -0.01f);
	private static final Vector2f CONTROL_VELOCITY = new Vector2f(1, 1);

	private Vector2f controlVelocity;
	private Image image;
	private MotionComponent motion;
	private LifeComponent life;
	private CollisionComponent hitbox;

	public Rocket() {
		controlVelocity = new Vector2f();
		life = new LifeComponent(MAX_LIFE);
		hitbox = new CollisionComponent();
		motion = new MotionComponent();
	}

	@Override
	public void init() throws SlickException {
		image = ImageManager.getImage("rocket-small.png");
		hitbox.setShape(new Rectangle(-image.getWidth() / 2, -image.getHeight() / 2,
				image.getWidth(), image.getHeight()));
		hitbox.moveTo(0, 0);
		motion.setVelocity(0, 0);
		life.setLife(MAX_LIFE);
	}

	@Override
	public void update(Input input, int delta) throws SlickException {
		// Reset affected attributes
		motion.setGravity(GRAVITY.x, GRAVITY.y);
		controlVelocity = new Vector2f(CONTROL_VELOCITY);

		// Handle input
		if (input.isKeyDown(Input.KEY_LEFT)) {
			hitbox.moveBy(delta * -controlVelocity.x, 0);
		}
		if (input.isKeyDown(Input.KEY_RIGHT)) {
			hitbox.moveBy(delta * controlVelocity.x, 0);
		}
		if (input.isKeyDown(Input.KEY_UP)) {
			hitbox.moveBy(0, -delta * controlVelocity.y);
			motion.setVelocityY(0);
		}
		if (input.isKeyDown(Input.KEY_DOWN)) {
			hitbox.moveBy(0, -delta * -controlVelocity.y);
			motion.setVelocityY(0);
		}
		motion.update(delta);
		Vector2f v = motion.getVelocity();
		hitbox.moveBy(delta * v.x, -delta * v.y);
	}

	@Override
	public void render(Graphics graphics) throws SlickException {
		// Save graphics context
		graphics.pushTransform();
		graphics.translate(-hitbox.getWidth() / 2, -hitbox.getHeight() / 2);

		// Draw the image
		graphics.drawImage(image, hitbox.getX(), hitbox.getY());

		// Restore previous context
		graphics.popTransform();

		// DEBUG
//		hitbox.debug(graphics);
	}

	public void applyEffect(RocketEffect effect) {
		effect.applyToRocket(this);
	}

	public void giveBoost(float amplitude) {
		motion.accelerate(0, amplitude);
	}

	public Vector2f getControlVelocity() {
		return controlVelocity;
	}

	public void setControlVelocity(float x, float y) {
		controlVelocity.x = x;
		controlVelocity.y = y;
	}

	@Override
	public CollisionComponent getCollisionComponent() {
		return hitbox;
	}

	public LifeComponent getLifeComponent() {
		return life;
	}
}
